#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>
#include "protocol.h"
#include "video.h"
#include "camera.h"
#include "download.h"
#include "ota.h"
#include "../utils/log.h"
#include "../utils/config.h"

// 协议常量定义
#define PROTOCOL_SYNC_BYTE1     0xAA
#define PROTOCOL_SYNC_BYTE2     0x55
#define PROTOCOL_HEADER_SIZE    sizeof(protocol_header_t)
#define PROTOCOL_CHECKSUM_SIZE  sizeof(uint16_t)
#define MAX_PACKET_SIZE         1024
#define DEFAULT_SERIAL_PORT     "/dev/ttyUSB0"
#define DEFAULT_BAUD_RATE       B115200

// 全局变量
static bool g_is_initialized = false;
static bool g_is_running = false;
static int g_serial_fd = -1;
static pthread_mutex_t g_protocol_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_status_mutex = PTHREAD_MUTEX_INITIALIZER;
static drone_status_t g_drone_status;
static uint16_t g_next_seq_num = 1;

// 初始化串口 - 暂时未使用但保留接口
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static int serial_init(const char *port, speed_t baud_rate)
{
    int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0) {
        LOG_ERROR("打开串口失败: %s, 错误: %s", port, strerror(errno));
        return -1;
    }
    
    // 获取并配置串口参数
    struct termios options;
    if (tcgetattr(fd, &options) != 0) {
        LOG_ERROR("获取串口属性失败: %s", strerror(errno));
        close(fd);
        return -1;
    }
    
    // 设置波特率
    cfsetispeed(&options, baud_rate);
    cfsetospeed(&options, baud_rate);
    
    // 8N1配置
    options.c_cflag &= ~PARENB; // 无校验位
    options.c_cflag &= ~CSTOPB; // 1个停止位
    options.c_cflag &= ~CSIZE;  // 清除数据位设置
    options.c_cflag |= CS8;     // 8个数据位
    options.c_cflag &= ~CRTSCTS; // 无硬件流控
    options.c_cflag |= CREAD | CLOCAL; // 启用接收，忽略调制解调器控制信号
    
    // 设置为原始模式
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL);
    options.c_oflag &= ~OPOST;
    
    // 设置超时
    options.c_cc[VMIN] = 0;
    options.c_cc[VTIME] = 10; // 1秒超时
    
    if (tcsetattr(fd, TCSANOW, &options) != 0) {
        LOG_ERROR("设置串口属性失败: %s", strerror(errno));
        close(fd);
        return -1;
    }
    
    tcflush(fd, TCIFLUSH);
    return fd;
}
#pragma GCC diagnostic pop

// 计算校验和
static uint16_t calculate_checksum(uint8_t *data, uint16_t len)
{
    uint16_t checksum = 0;
    for (uint16_t i = 0; i < len; i++) {
        checksum += data[i];
    }
    return checksum;
}

// 解析协议包
static int parse_packet(uint8_t *buffer, uint16_t len, protocol_packet_t *packet)
{
    if (len < PROTOCOL_HEADER_SIZE + PROTOCOL_CHECKSUM_SIZE) {
        return PROTOCOL_ERROR_PARSE;
    }
    
    // 解析包头
    memcpy(&packet->header, buffer, PROTOCOL_HEADER_SIZE);
    
    // 验证同步字节
    if (packet->header.sync_byte1 != PROTOCOL_SYNC_BYTE1 || 
        packet->header.sync_byte2 != PROTOCOL_SYNC_BYTE2) {
        return PROTOCOL_ERROR_PARSE;
    }
    
    // 验证长度
    if (packet->header.length != len) {
        return PROTOCOL_ERROR_PARSE;
    }
    
    // 解析包体
    uint16_t payload_len = len - PROTOCOL_HEADER_SIZE - PROTOCOL_CHECKSUM_SIZE;
    packet->payload.data = buffer + PROTOCOL_HEADER_SIZE;
    packet->payload.data_len = payload_len;
    
    // 解析校验和
    memcpy(&packet->checksum, buffer + len - PROTOCOL_CHECKSUM_SIZE, PROTOCOL_CHECKSUM_SIZE);
    
    // 验证校验和
    uint16_t calculated_checksum = calculate_checksum(buffer, len - PROTOCOL_CHECKSUM_SIZE);
    if (calculated_checksum != packet->checksum) {
        return PROTOCOL_ERROR_PARSE;
    }
    
    return PROTOCOL_SUCCESS;
}

// 构建协议包
static int build_packet(protocol_packet_t *packet, uint8_t *buffer, uint16_t *buffer_len)
{
    uint16_t total_len = PROTOCOL_HEADER_SIZE + packet->payload.data_len + PROTOCOL_CHECKSUM_SIZE;
    
    if (*buffer_len < total_len) {
        return PROTOCOL_ERROR_SEND;
    }
    
    // 设置包头
    packet->header.sync_byte1 = PROTOCOL_SYNC_BYTE1;
    packet->header.sync_byte2 = PROTOCOL_SYNC_BYTE2;
    packet->header.length = total_len;
    packet->header.seq_num = g_next_seq_num++;
    
    // 复制包头到缓冲区
    memcpy(buffer, &packet->header, PROTOCOL_HEADER_SIZE);
    
    // 复制包体到缓冲区
    if (packet->payload.data_len > 0 && packet->payload.data != NULL) {
        memcpy(buffer + PROTOCOL_HEADER_SIZE, packet->payload.data, packet->payload.data_len);
    }
    
    // 计算并添加校验和
    packet->checksum = calculate_checksum(buffer, total_len - PROTOCOL_CHECKSUM_SIZE);
    memcpy(buffer + total_len - PROTOCOL_CHECKSUM_SIZE, &packet->checksum, PROTOCOL_CHECKSUM_SIZE);
    
    *buffer_len = total_len;
    return PROTOCOL_SUCCESS;
}

// 处理视频开始命令
static int handle_video_start_cmd(protocol_packet_t *packet)
{
    int ret = video_start_recording(NULL);
    if (ret == VIDEO_SUCCESS) {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_SUCCESS, NULL, 0);
    } else {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_FAILED, (uint8_t*)&ret, sizeof(ret));
    }
}

// 处理视频停止命令
static int handle_video_stop_cmd(protocol_packet_t *packet)
{
    int ret = video_stop_recording();
    if (ret == VIDEO_SUCCESS) {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_SUCCESS, NULL, 0);
    } else {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_FAILED, (uint8_t*)&ret, sizeof(ret));
    }
}

// 处理拍照命令
static int handle_camera_capture_cmd(protocol_packet_t *packet)
{
    int ret = camera_capture_photo(NULL, NULL);
    if (ret == CAMERA_SUCCESS) {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_SUCCESS, NULL, 0);
    } else {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_FAILED, (uint8_t*)&ret, sizeof(ret));
    }
}

// 处理获取状态命令
static int handle_get_status_cmd(protocol_packet_t *packet)
{
    drone_status_t status;
    int ret = protocol_get_drone_status(&status);
    if (ret == PROTOCOL_SUCCESS) {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_SUCCESS, (uint8_t*)&status, sizeof(status));
    } else {
        return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                    RESP_STATUS_FAILED, (uint8_t*)&ret, sizeof(ret));
    }
}

// 处理心跳命令
static int handle_heartbeat_cmd(protocol_packet_t *packet)
{
    return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                RESP_STATUS_SUCCESS, NULL, 0);
}

// 处理命令包
static int process_command(protocol_packet_t *packet)
{
    LOG_INFO("收到命令: 类型=%d, ID=%d, 序列号=%d, 数据长度=%d",
             packet->header.cmd_type, packet->header.cmd_id,
             packet->header.seq_num, packet->payload.data_len);
    
    switch (packet->header.cmd_type) {
        case CMD_TYPE_VIDEO_START:
            return handle_video_start_cmd(packet);
        case CMD_TYPE_VIDEO_STOP:
            return handle_video_stop_cmd(packet);
        case CMD_TYPE_CAMERA_CAPTURE:
            return handle_camera_capture_cmd(packet);
        case CMD_TYPE_GET_STATUS:
            return handle_get_status_cmd(packet);
        case CMD_TYPE_HEARTBEAT:
            return handle_heartbeat_cmd(packet);
        // 其他命令类型的处理...
        default:
            LOG_WARN("未知命令类型: %d", packet->header.cmd_type);
            return protocol_send_response(packet->header.cmd_id, packet->header.seq_num,
                                        RESP_STATUS_INVALID, NULL, 0);
    }
}

// 更新无人机状态
static void update_drone_status(void)
{
    pthread_mutex_lock(&g_status_mutex);
    
    g_drone_status.is_video_recording = video_is_recording();
    g_drone_status.is_camera_available = camera_is_available();
    
    // 模拟电池电量和温度
    g_drone_status.current_battery_level = 85; // 85%
    g_drone_status.current_temperature = 35.5f;
    
    // 获取固件版本
    ota_get_current_version(g_drone_status.firmware_version, sizeof(g_drone_status.firmware_version));
    
    // 模拟存储空间
    g_drone_status.free_storage_bytes = 1024 * 1024 * 1024; // 1GB
    
    pthread_mutex_unlock(&g_status_mutex);
}

void *protocol_thread_func(void *arg)
{
    (void)arg; // 未使用的参数
    
    pthread_mutex_lock(&g_protocol_mutex);
    g_is_running = true;
    pthread_mutex_unlock(&g_protocol_mutex);
    
    LOG_INFO("协议处理线程启动");
    
    uint8_t buffer[MAX_PACKET_SIZE];
    uint16_t received_len = 0;
    
    // 协议线程主循环
    while (g_is_running) {
        // 更新状态信息
        update_drone_status();
        
        // 尝试从串口读取数据
        if (g_serial_fd >= 0) {
            int bytes_read = read(g_serial_fd, buffer + received_len, MAX_PACKET_SIZE - received_len);
            if (bytes_read > 0) {
                received_len += bytes_read;
                
                // 尝试解析数据包
                protocol_packet_t packet;
                int ret = parse_packet(buffer, received_len, &packet);
                if (ret == PROTOCOL_SUCCESS) {
                    // 处理命令
                    process_command(&packet);
                    
                    // 清空缓冲区
                    received_len = 0;
                } else if (received_len >= MAX_PACKET_SIZE) {
                    // 缓冲区已满但仍未解析出有效包，清空缓冲区
                    LOG_WARN("协议缓冲区溢出，清空数据");
                    received_len = 0;
                }
            }
        }
        
        usleep(100000); // 100ms延迟
    }
    
    LOG_INFO("协议处理线程退出");
    return NULL;
}

int protocol_init(void)
{
    pthread_mutex_lock(&g_protocol_mutex);
    
    if (g_is_initialized) {
        pthread_mutex_unlock(&g_protocol_mutex);
        return PROTOCOL_SUCCESS;
    }
    
    // 初始化串口（这里使用模拟实现，实际环境中需要正确的串口配置）
    // g_serial_fd = serial_init(DEFAULT_SERIAL_PORT, DEFAULT_BAUD_RATE);
    // if (g_serial_fd < 0) {
    //     LOG_WARN("串口初始化失败，使用模拟模式");
    // }
    
    // 初始化无人机状态
    memset(&g_drone_status, 0, sizeof(drone_status_t));
    
    LOG_INFO("协议模块初始化成功");
    g_is_initialized = true;
    
    pthread_mutex_unlock(&g_protocol_mutex);
    return PROTOCOL_SUCCESS;
}

void protocol_cleanup(void)
{
    pthread_mutex_lock(&g_protocol_mutex);
    
    if (!g_is_initialized) {
        pthread_mutex_unlock(&g_protocol_mutex);
        return;
    }
    
    // 停止线程
    g_is_running = false;
    
    // 关闭串口
    if (g_serial_fd >= 0) {
        close(g_serial_fd);
        g_serial_fd = -1;
    }
    
    LOG_INFO("协议模块清理完成");
    g_is_initialized = false;
    
    pthread_mutex_unlock(&g_protocol_mutex);
}

int protocol_send_packet(protocol_packet_t *packet)
{
    pthread_mutex_lock(&g_protocol_mutex);
    
    if (!g_is_initialized) {
        pthread_mutex_unlock(&g_protocol_mutex);
        LOG_ERROR("协议模块未初始化");
        return PROTOCOL_ERROR_INIT;
    }
    
    uint8_t buffer[MAX_PACKET_SIZE];
    uint16_t buffer_len = MAX_PACKET_SIZE;
    
    int ret = build_packet(packet, buffer, &buffer_len);
    if (ret != PROTOCOL_SUCCESS) {
        pthread_mutex_unlock(&g_protocol_mutex);
        return ret;
    }
    
    // 模拟发送数据包
    LOG_INFO("发送数据包，长度: %d, 命令类型: %d", buffer_len, packet->header.cmd_type);
    
    // 实际环境中，这里应该通过串口发送数据
    // if (g_serial_fd >= 0) {
    //     int bytes_written = write(g_serial_fd, buffer, buffer_len);
    //     if (bytes_written != buffer_len) {
    //         pthread_mutex_unlock(&g_protocol_mutex);
    //         LOG_ERROR("发送数据包失败");
    //         return PROTOCOL_ERROR_SEND;
    //     }
    // }
    
    pthread_mutex_unlock(&g_protocol_mutex);
    return PROTOCOL_SUCCESS;
}

int protocol_send_response(uint8_t cmd_id, uint16_t seq_num, 
                          enum protocol_response_status status,
                          uint8_t *data, uint16_t data_len)
{
    protocol_packet_t response;
    memset(&response, 0, sizeof(response));
    
    response.header.cmd_type = CMD_TYPE_RESPONSE;
    response.header.cmd_id = cmd_id;
    response.header.seq_num = seq_num;
    response.payload.data = data;
    response.payload.data_len = data_len;
    
    // 在数据前添加状态码
    uint8_t *buffer = NULL;
    uint16_t buffer_len = 0;
    
    if (data_len > 0) {
        buffer_len = data_len + 1;
        buffer = (uint8_t *)malloc(buffer_len);
        if (!buffer) {
            LOG_ERROR("内存分配失败");
            return PROTOCOL_ERROR_SEND;
        }
        buffer[0] = status;
        memcpy(buffer + 1, data, data_len);
        response.payload.data = buffer;
        response.payload.data_len = buffer_len;
    } else {
        buffer_len = 1;
        buffer = (uint8_t *)malloc(buffer_len);
        if (!buffer) {
            LOG_ERROR("内存分配失败");
            return PROTOCOL_ERROR_SEND;
        }
        buffer[0] = status;
        response.payload.data = buffer;
        response.payload.data_len = buffer_len;
    }
    
    int ret = protocol_send_packet(&response);
    
    // 释放临时缓冲区
    if (buffer) {
        free(buffer);
    }
    
    return ret;
}

int protocol_get_drone_status(drone_status_t *status)
{
    pthread_mutex_lock(&g_status_mutex);
    
    if (!g_is_initialized) {
        pthread_mutex_unlock(&g_status_mutex);
        LOG_ERROR("协议模块未初始化");
        return PROTOCOL_ERROR_INIT;
    }
    
    if (status) {
        memcpy(status, &g_drone_status, sizeof(drone_status_t));
    }
    
    pthread_mutex_unlock(&g_status_mutex);
    return PROTOCOL_SUCCESS;
}